// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// o [author] rhyme_lph
// J [email]  rhymelph@gmail.com
// J [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/payment_term_entity.dart';
import 'package:finance_app/src/entities/setting_alerts_entity.dart';
import 'package:finance_app/src/entities/setting_data_entity.dart';
import 'package:finance_app/src/entities/setting_info_entity.dart';
import 'package:finance_app/src/http_service/http_setting_service.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/widgets/bottom_sheet/currency_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/list_select_bottom_sheet.dart';

class PreferencesProvider extends BaseProvider {
  SettingDataCurrency currency;

  @override
  Future get dataFuture => null;

  @override
  void initState() {
    super.initState();
    _loadSettingInfo();
  }

  void onChangeLanguage() {
    obtainContext?.call((context) async {
      final selectedLanguage =
          await showLanguageSelectBottomSheet(context, Config.languageCode);
      if (selectedLanguage != Config.languageCode) {
        BaseConfig.dialogBase
            .showLoadingDialog(context: context, text: 'Loading');
        await post(
            HttpSettingService.updateSettingInfo(
              language: selectedLanguage,
            ), onSuccess: (result) async {
          Config.settingInfo.language = selectedLanguage;
          await RProvider.myProvider.updateGlobalMap();
          Routes.navigateTo(RouterGenProviders.dashboardPage,
              clearStack: true, replace: true);
        });
      }
    });
  }

  void onNumberFormat() {
    Routes.navigateTo(RouterGenProviders.numberFormatPage);
  }

  void onTemplateStyle() {
    Routes.navigateTo(RouterGenProviders.templateStylePage);
  }

  void onUnitOfMeasurement() {
    Routes.navigateTo(RouterGenProviders.unitOfMeasurementPage);
  }

  void onChangeCurrency() {
    obtainContext?.call((context) async {
      final result = await showCurrencyBottomSheet(
          context, Config.settingInfo.currencyCode);
      if (result != null && result != Config.settingInfo) {
        SettingDataCurrency currency = result;
        await post(
            HttpSettingService.updateSettingInfo(
              default_currency_code: currency.key,
            ),
            autoHandler: AutoHandler.Toast,
            loadingTip: S.current.loading, onSuccess: (result) async {
          Config.settingInfo.defaultCurrencyCode = currency.key;
          await RProvider.myProvider.updateGlobalMap();
        });
      }
    });
  }

  void onChangePaymentType() {
    obtainContext?.call((context) async {
      final result = await showPaymentMethodBottomSheet(
          context, Config.settingInfo.paymentType);
      if (result != null && result != Config.settingInfo.paymentType) {
        SettingDataPaymentType paymentType = result;
        await post(
            HttpSettingService.updateSettingInfo(
              default_payment_type_id: paymentType.id,
            ),
            autoHandler: AutoHandler.Toast,
            loadingTip: S.current.loading, onSuccess: (result) async {
          Config.settingInfo.defaultPaymentTypeId = paymentType.id;
          await RProvider.myProvider.updateGlobalMap();
        });
      }
    });
  }

  void onChangePaymentTerm() {
    obtainContext?.call((context) async {
      final result =
          await showPaymentTermBottomSheet(context, Config.paymentTerm);
      if (result != null && result != Config.paymentTerm) {
        PaymentTermEntity paymentTerm = result;
        await post(
            HttpSettingService.updateSettingInfo(
              default_payment_term_id: paymentTerm.id,
            ),
            autoHandler: AutoHandler.Toast,
            loadingTip: S.current.loading, onSuccess: (result) async {
          Config.settingInfo.defaultPaymentTermId = paymentTerm.id;
          await RProvider.myProvider.updateGlobalMap();
        });
      }
    });
  }

  void onChangeTaxType() async {
    obtainContext?.call((context) async {
      final result =
          await showGstRateBottomSheet(context, Config.settingInfo.taxData);
      if (result != null && result != Config.settingInfo.taxData) {
        final taxType = result;
        await post(
            HttpSettingService.updateSettingInfo(
              tax_id: taxType.id,
            ),
            autoHandler: AutoHandler.Toast,
            loadingTip: S.current.loading, onSuccess: (result) async {
          Config.settingInfo.taxId = taxType.id;
          await RProvider.myProvider.updateGlobalMap();
        });
      }
    });
  }

  void onChangeDateFormat() {
    obtainContext?.call((context) async {
      final result = await showDateFormatSelectBottomSheet(
          context, Config.settingInfo.dateFormat);
      if (result != null && result != Config.settingInfo.dateFormat) {
        final settingInfo = Config.settingInfo..dateFormat = result;
        await post(
            HttpSettingService.updateSettingInfo(
              date_format: settingInfo.dateFormat,
            ),
            autoHandler: AutoHandler.Toast,
            loadingTip: S.current.loading, onSuccess: (result) async {
          RProvider.myProvider.globalMap[ConfigKey.settingInfo] = settingInfo;
          await RProvider.myProvider.updateGlobalMap();
          update();
        });
      }
    });
  }

  void onCheckAlertSetting(SettingAlertsEntity e) async {
    List<String> templateAlerts = List.from(Config.settingInfo.alerts);
    if (templateAlerts.contains(e.key)) {
      templateAlerts.remove(e.key);
    } else {
      templateAlerts.add(e.key);
    }
    bool isSuccess = false;
    await post(
        HttpSettingService.updateSettingInfo(
          alerts: templateAlerts,
        ),
        autoHandler: AutoHandler.Toast,
        loadingTip: S.current.loading, onSuccess: (result) {
      isSuccess = true;
    });
    if (isSuccess == true) {
      Config.settingInfo.alerts = templateAlerts;
      await RProvider.myProvider.updateGlobalMap();
    }
  }

  void _loadSettingInfo() {
    post(HttpSettingService.getSettingInfo(), autoHandler: AutoHandler.Toast,
        onSuccess: (result) async {
      RProvider.myProvider.globalMap[ConfigKey.settingInfo] =
          getEntityFromResult<SettingInfoEntity>(result);
      await RProvider.myProvider.updateGlobalMap();
    });
  }
}
